Skip to content

feat(js): add lifecycle-managed js.io() to the JS DSL#26

Merged
nazarhussain merged 3 commits into
mainfrom
nh/napi-io
Jul 1, 2026
Merged

feat(js): add lifecycle-managed js.io() to the JS DSL#26
nazarhussain merged 3 commits into
mainfrom
nh/napi-io

Conversation

@nazarhussain

Copy link
Copy Markdown
Contributor

Motivation

We already expose lifecycle-scoped DSL context helpers like js.env() and js.allocator(). This change adds the analogous I/O surface so DSL code can use std.Io facilities without requiring module authors to bootstrap or own a separate runtime.

Summary

  • adds a public js.io() accessor to the JS DSL
  • backs js.io() with a shared std.Io.Threaded instance retained for the lifetime of active addon environments
  • wires retain/release into js.exportModule(...) so consumers do not need any manual setup

API Notes

  • the public API is js.io()
  • retain() / release() remain internal implementation details
  • module consumers should not call any manual retain API
  • js.io() is only valid during the normal addon lifecycle window and will panic if used before registration or after final cleanup

@nazarhussain nazarhussain requested a review from wemeetagain May 18, 2026 15:10
Comment thread src/js/export_module.zig Outdated
Comment on lines +211 to +212
test "exportModule cleanup hook now also backs shared js.io lifecycle" {
try std.testing.expect(true);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change seems fishy?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was actually supposed to delete the full test case. Now added a particular test case for retain/cleanup scenario.

Comment thread src/js/io.zig Outdated

const gpa: std.mem.Allocator = std.heap.page_allocator;

const SpinLock = struct {

@spiral-ladder spiral-ladder Jul 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering why not just use std.Io.Mutex here instead of handrolling a spin lock?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The std.io.Mutex was not used earlier because it's .lock take an io as parameter. And in our case we are actually protecting the io itselt. Now used std.Io.Threaded.mutexLock which does not need io.

nazarhussain and others added 2 commits July 1, 2026 16:05
Replace the vacuous expect(true) placeholder with a real check that
io() returns the same backing instance across calls while retained,
guarding the shared-io lifecycle the env cleanup hook drives.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the hand-rolled spin lock with std.Io.Mutex locked via
std.Io.Threaded.mutexLock/mutexUnlock, which need no Io argument and
block on a futex instead of busy-spinning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@spiral-ladder spiral-ladder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@nazarhussain nazarhussain merged commit fbb0801 into main Jul 1, 2026
5 checks passed
@nazarhussain nazarhussain deleted the nh/napi-io branch July 1, 2026 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants